<?php
declare(strict_types=1);

namespace Service\CommodityService;

use App\Model\CommodityModel\Stockinfo;
use App\Model\CommodityModel\SupplierCommodity;
use Hyperf\DbConnection\Db;
use Service\AppService\IdService;
use Service\BaseService;
use Service\Code\Normal;
use Service\CommodityCustomInfoService\SupplierCommodityCustomInfoService;
use Service\ConsumerService\ConsumerMapping\CommodityMapping;
use Service\HsCodeService\HsCodeService;
use Service\StockInfoService\StockInfoService;

class SupplierCommodityService extends BaseService
{
    const COMMODITY_CHUNK_NUM = 50;

    /**
     * 根据供应商Id 批量下架 供应商商品
     * @param int $supplierId 供应商Id
     * @param int $toPush
     * @return array
     */
    public function batchCommodityDown(int $supplierId, int $toPush = 0): array
    {
        //需要下架的id
        $commodityIdsObj = SupplierCommodity::instance()
            ->where('SupplierCompanyID', $supplierId)
            ->where('IsNeedGoodsDown', 1)
            ->pluck('ID');
        if (empty($commodityIdsObj)) {
            return Normal::returnCode(
                Normal::SUC,
                '没有需要下架的商品'
            );
        }
        $commodityIds = $commodityIdsObj->toArray();
        //这边进行分组
        $commodityChunk = array_chunk($commodityIds, self::COMMODITY_CHUNK_NUM);
        //todo 这里完成消息推送以及商品数据库的修改
        return Normal::returnSuccessCode();
    }

    /**
     * 根据供应商Id 将该供应商商品全部置为待下架状态
     * @param int $supplierId 供应商Id
     * @return array
     */
    public function changeCommodityDownStatus($supplierId)
    {
        SupplierCommodity::instance()->where('SupplierCompanyID', $supplierId)
            ->update([
                'IsNeedGoodsDown' => 1
            ]);
        return Normal::returnCode(Normal::SUC, '修改成功');
    }

    /**
     * 获取消费队列的前置数据
     * @param $skuCodes array 供应商sku
     * @param $supplierInfo array 供应商详情
     * @return array
     */
    public function getPreConsumerData($skuCodes, $supplierInfo)
    {
        //获取已存在的商品
        $oldCommodities = $this->getOldConsumerCommodity($skuCodes, $supplierInfo['SupplierID']);
        $commodityStockMapping = $customMapping = [];
        if (!empty($oldCommodities)) {
            //获取已存在的库存信息
            $oldCommodityMapping = array_column($oldCommodities, 'SupplierCommoditySkuCode', 'ID');
            $commodityStockMapping = StockInfoService::instance()->getOldConsumerStockInfos($oldCommodityMapping);
            //判断该供应商是否需要商品备案信息
            if ($supplierInfo['OrderDeclare'] == 1) {
                //获取已存在的商品备案信息
                $customInfos = SupplierCommodityCustomInfoService::instance()->getOldConsumerCustomInfos(array_keys($oldCommodityMapping));
                $customMapping = array_column($customInfos, null, 'SupplierCommodityID');
            }
        }

        return ['goodsMapping' => $oldCommodities, 'stockMapping' => $commodityStockMapping, 'customMapping' => $customMapping, 'HsCodeMapping' => HsCodeService::instance()->getConsumerHsCodes()];

    }

    /**
     * 获取已存在的供应商商品数据
     * @param $supplierSkuCodes
     * @param $supplierId
     * @return array
     */
    public function getOldConsumerCommodity($supplierSkuCodes, $supplierId)
    {
        $data = SupplierCommodity::instance()
            ->from(SupplierCommodity::instance()->getTable() . ' as sc')
            ->Leftjoin('commodityarchives_s2b as c', 'c.ID', '=', 'sc.CommodityArchivesID')
            ->select([
                Db::raw('concat(sc.ID,"") AS ID'),
                'sc.SupplierCompanyID',
                'sc.SupplierCommoditySkuCode',
                'sc.DefaultStock',
                'sc.TaxRate',
                'sc.SupplierCommodityDescription',
                'sc.SupplierCommodityUinit',
                'sc.SupplierCommodityBrand',
                'sc.SupplierCommodityClassify',
                'sc.SupplierCommodityOriginPlace',
                'sc.SupplierCommodityInternationBarCode',
                'sc.SupplierCommodityType',
                'sc.SupplierCommodityImageUrl',
                'sc.SupplierCommodityName',
                'sc.SupplierCommodityKey',
                'sc.SaleType',
                'sc.SKUCode',
                'sc.CommodityArchivesID',
                'sc.HSCode',
                'sc.DeclarePlanCode',
                'sc.IsHaveTaxRate',
                'sc.UpstreamSaleType',
                'sc.DeliveryMethod',
                'sc.PriceControlType',
                'sc.IsFreeShipping',
                'sc.LimitOrControlPrice',
                'sc.IsNeedWeiXinPay',
                'sc.IsNeedUploadIDCard',
                'sc.IsNeedIDCard',
                'c.Weight',
                'sc.FreightTemplate',
                'sc.ConSumptionTaxRate',
                'sc.ConSumptionPrice'
            ])
            ->whereIn('SupplierCommoditySkuCode', $supplierSkuCodes)
            ->where('SupplierCompanyID', $supplierId)->get()->toArray();

        return array_column($data, NULL, 'SupplierCommoditySkuCode');

    }

    /**
     * 消息队列添加商品
     * @param $goodsMapping
     * @param $supplierInfo
     * @return array
     */
    public function insertConsumerCommodity($pendingItem, $supplierInfo): array
    {
        $goodsMapping = $pendingItem['goodsMapping'];
        SupplierCommodity::instance()->startTrans();
        try {
            $goodsBase = $goodsMapping['base'];
            $currentTime = date('Y-m-d H:i:s');
            $goodsBase['ID'] = IdService::instance()->getOtherID();
            $goodsBase['CreateTime'] = $currentTime;
            $goodsBase['UpdateTime'] = $currentTime;
            $goodsBase['SupplierCompanyID'] = $supplierInfo['SupplierID'];
            $goodsBase['SaleType'] = 1;
            SupplierCommodity::instance()->insert($goodsBase);
            //判断供应商是否需要订单申报
            if ($supplierInfo['OrderDeclare'] == 1 && !empty($goodsMapping['custominfo'])) {
                $goodsCustomInfo = $goodsMapping['custominfo'];
                $goodsCustomInfo['GoodsInfoID'] = $goodsBase['ID'];
                CommodityCustomInfoService::instance()->insertConsumerCustomInfo($goodsCustomInfo);
            }
            //添加库存信息
            StockInfoService::instance()->insertConsumerStockInfo($goodsMapping, $supplierInfo);
            //添加标签信息
            if (!empty($goodsMapping['tags'])) {
                SupplierCommodityTagService::instance()->insertConsumerTags($goodsMapping['tags'], $goodsBase['ID']);
            }
            SupplierCommodity::instance()->commit();
        } catch (\Exception $exception) {
            SupplierCommodity::instance()->rollback();
            return Normal::returnCode(Normal::FAIL, '商品新增失败:' . $exception->getMessage());
        }
        return Normal::returnCode(Normal::SUC, '商品新增成功', ['ID' => $goodsBase['ID'],'toPush'=>1]);
    }

    /**
     * 消息队列添加商品
     * @param $goodsMapping
     * @param $supplierInfo
     * @return array
     */
    public function updateConsumerCommodity($pendingItem, $supplierInfo, $validateType): array
    {
        SupplierCommodity::instance()->startTrans();
        $toPush = 0;
        try {

            $goodsMapping = $pendingItem['goodsMapping'];
            $goodsBase = $goodsMapping['base'];
            $oldGoodsMapping = $pendingItem['oldGoodsMapping'];
            $oldGoodsBase = $oldGoodsMapping['base'];
            $StockPriceChange = false;

            $CommodityChange = SupplierCommodityValidateService::instance()->checkCommodityUpdateChange($pendingItem, $validateType);
            if ($CommodityChange) {
                $upstreamSaleType = CommodityMapping::instance()->upstreamSaleType;
                //同步模式 0 同步资料和库存 1 只同步库存
                if ($supplierInfo['SyncMode'] == 0) {
                    SupplierCommodity::instance()->where('ID', $oldGoodsBase['ID'])->update($goodsBase);
                } elseif ($goodsBase[$upstreamSaleType] != $oldGoodsBase[$upstreamSaleType]) {
                    //只下架商品
                    SupplierCommodity::instance()->where('ID', $oldGoodsBase['ID'])->update([
                        $upstreamSaleType => $goodsBase[$upstreamSaleType]
                    ]);
                }
            }
            $commodityArchivesID = CommodityMapping::instance()->commodityArchivesID;
            //这边判断主资料ID是否已经变更,如已经变更则需要修改库存表里的主资料Id
            if (isset($goodsBase[$commodityArchivesID]) && $goodsBase[$commodityArchivesID] != $oldGoodsBase[$commodityArchivesID]) {
                StockInfoService::instance()->changeStockInfoCommodityArchivesID($oldGoodsBase['ID'], $goodsBase[$commodityArchivesID]);
            }
            //判断是否需要修改商品主资料重量
            if (!empty($oldGoodsMapping['other']['weight']) && $oldGoodsBase['Weight'] == 0 && $oldGoodsBase[$commodityArchivesID]) {
                CommodityArchivesService::instance()->changeCommodityArchivesWeight($oldGoodsMapping['other']['weight'], $oldGoodsBase[$commodityArchivesID]);
                //这里需要重新根据重量计算价格
                $StockPriceChange = true;
            }

            //库存数据是否有变动
            $StockChange = SupplierCommodityValidateService::instance()->checkStockInfoUpdateChange($pendingItem, $supplierInfo);
            if ($StockChange && (!empty($goodsMapping['stock']) || !empty($goodsMapping['isDownBatchNo']))) {
                StockInfoService::instance()->updateConsumerStockInfo($pendingItem, $supplierInfo);
            } elseif ($StockPriceChange) {
                StockInfoService::instance()->updateConsumerStockInfoPrice($pendingItem, $supplierInfo);
            }
            //添加标签信息
            if (!empty($goodsMapping['tags'])) {
                SupplierCommodityTagService::instance()->insertConsumerTags($goodsMapping['tags'], $goodsBase['ID'], true);
            }
            SupplierCommodity::instance()->commit();
        } catch (\Exception $exception) {
            SupplierCommodity::instance()->rollback();
            return Normal::returnCode(Normal::FAIL, '商品修改失败:' . $exception->getMessage());
        }
        //判断差异的字段是否有需要推送给优化队列的字段
        if ($CommodityChange || $StockChange) {
            $toPush = true;
        }
        return Normal::returnCode(Normal::SUC, '商品修改成功', ['ID' => $oldGoodsBase['ID'],'toPush'=>$toPush]);
    }

    /**
     * 修改商品是否需要下架处理状态字段
     * @param $skuIds
     * @return array
     */
    public function ChangeGoodsUp($skuIds)
    {
        if ($skuIds){
            SupplierCommodity::instance()
                ->whereIn('ID',$skuIds)
                ->update([
                    'IsNeedGoodsDown'=> 0,
                    'UpdateTime'=>date('Y-m-d H:i:s')
                ]);
        }
        return Normal::returnCode(Normal::SUC,'修改成功');
    }

}